package com.xzj.common.file.excel.util;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.WriteSheet;
import lombok.extern.slf4j.Slf4j;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * @program: xzj-test
 * @ClassName: NewExcelUtil
 * @description: xxx
 * @author: XiaZunJun
 * @create: 2024-08-21 14:22
 */
@Slf4j
public class EasyExcelExportUtil {

    /**
     * 创建xlsx导出开始（适用于多个sheet）
     * ExcelUtil.finishWrite(writer);
     *
     * @param response
     * @param fileName 导出的文件名，不需要加.xlsx 不自定义导出格式
     */
    public static ExcelWriter createExport(HttpServletResponse response, String fileName) {
        OutputStream outputStream = getOutputStream(response, fileName);
        return EasyExcel.write(outputStream).build();
    }

    /**
     * 创建xlsx导出开始（适用于多个sheet）
     * ExcelUtil.finishWrite(writer);
     *
     * @param response
     * @param fileName 导出的文件名，不需要加.xlsx
     * @param cellWriteHandler 自定义单元格样式
     */
    public static ExcelWriter createExport(HttpServletResponse response, String fileName,CellWriteHandler cellWriteHandler) {
        OutputStream outputStream = getOutputStream(response, fileName);
        return EasyExcel.write(outputStream).registerWriteHandler(cellWriteHandler).build();
    }

    private static OutputStream getOutputStream(HttpServletResponse response, String fileName) {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        try {
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("导出XLS时发送错误");
        }
        OutputStream outputStream;
        try {
            outputStream = response.getOutputStream();
        } catch (IOException e) {
            throw new RuntimeException("导出XLS发送错误");
        }
        return outputStream;
    }


    /**
     * 写入一个sheet
     *
     * @param sheetName   工作表名
     * @param list<T> 需要导出的实体的集合
     * @param entityClass 需要导出的实体Class
     */
    public static <T> void writeSheet(ExcelWriter excelWriter, String sheetName, List<T> list, Class<?> entityClass) {
        WriteSheet sheet = EasyExcel.writerSheet(sheetName).head(entityClass).build();
        excelWriter.write(list, sheet);
    }

    /**
     * 写入一个sheet
     *
     * @param sheetName   工作表名
     * @param list<T>     需要导出的实体的集合
     * @param fieldList 需要导出的实体中的具体字段名
     * @param headList 需要导出的实体列的名称
     */
    public static <T> void writeSheet(ExcelWriter excelWriter, String sheetName, List<T> list,List<String> fieldList,List<List<String>> headList) {
        WriteSheet sheet = EasyExcel.writerSheet(sheetName).head(headList).includeColumnFieldNames(fieldList).build();
        excelWriter.write(list, sheet);
    }

    /**
     * 结束写入sheet并导出
     */
    public static void finishWrite(ExcelWriter excelWriter) {
        excelWriter.finish();
    }

    /**
     * 导入Excel
     * @author XiaZunJun
     * @date 2024/8/26 上午9:24
     * @param inputStream  输入流
     * @param entityClass    导入的实体Class
     * @return List<T> 返回导入的实体集合
     */
    public static <T> List<T> uploadExcel(InputStream inputStream, Class<T> entityClass) {
        List<T> resultList = new ArrayList<>();
        EasyExcel.read(inputStream, entityClass, new PageReadListener<T>(resultList::addAll,Integer.MAX_VALUE)).sheet().doRead();
        return resultList;
    }

}
